#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
通信管理器
管理TCP和串口通信，支持二选一互斥模式
"""

import logging
import time
from datetime import datetime
from typing import Optional, Callable, Dict, Any
from PyQt6.QtCore import QObject, pyqtSignal

# 导入TCP协议
try:
    from src.protocols.tcp.tcp_protocol import TCPClient, TCPCommunicationThread
    TCP_AVAILABLE = True
except ImportError as e:
    logging.warning(f"导入TCP模块失败: {e}")
    TCP_AVAILABLE = False

# 导入串口协议
try:
    from src.protocols.serial.serial_protocol import SerialPort, SerialCommunicationThread, CustomLISParser
    SERIAL_AVAILABLE = True
except ImportError as e:
    logging.warning(f"导入串口模块失败: {e}")
    SERIAL_AVAILABLE = False

# 导入数据处理器
try:
    from src.core.data_processor import DataProcessor
    DATA_PROCESSOR_AVAILABLE = True
except ImportError as e:
    logging.warning(f"导入数据处理器失败: {e}")
    DATA_PROCESSOR_AVAILABLE = False

logger = logging.getLogger(__name__)

class CommunicationType:
    """通信类型枚举"""
    SERIAL = "串口"
    TCP = "TCP"

class CommunicationManager(QObject):
    """通信管理器 - 支持TCP和串口二选一互斥模式"""
    
    # 信号定义
    data_received = pyqtSignal(bytes)
    message_processed = pyqtSignal(dict)
    connection_status_changed = pyqtSignal(bool)
    error_occurred = pyqtSignal(str)
    
    def __init__(self, db_manager=None):
        super().__init__()
        
        # 通信状态
        self.serial_port = None
        self.tcp_client = None
        self.tcp_server = None
        self.is_connected = False
        self.data_callback = None
        self.comm_thread = None
        self.message_count = 0
        self.db_manager = db_manager
        
        # 通信类型 - 默认使用TCP
        self.communication_type = CommunicationType.TCP
        
        # 数据处理器
        if DATA_PROCESSOR_AVAILABLE:
            self.data_processor = DataProcessor()
        else:
            self.data_processor = None
            logger.warning("数据处理器不可用")
        
        # 系统日志管理器
        try:
            from src.utils.logger_manager import get_system_logger
            self.system_logger = get_system_logger()
        except ImportError:
            self.system_logger = None
        
        # 协议解析器
        self.parsers = {}
        self.register_parsers()
        
        logger.info("通信管理器初始化完成")

    def register_parsers(self):
        """注册协议解析器"""
        # 注册自定义LIS协议解析器（串口版本）
        try:
            if SERIAL_AVAILABLE:
                from src.protocols.serial.serial_protocol import CustomLISParser
                self.parsers['custom_lis'] = CustomLISParser()
                logger.info("自定义LIS协议解析器（串口）注册成功")
            else:
                logger.warning("串口模块不可用，自定义LIS协议解析器不可用")
        except Exception as e:
            logger.warning(f"自定义LIS协议解析器（串口）不可用: {e}")
        
        # 注册自定义LIS协议解析器（TCP版本）
        try:
            if TCP_AVAILABLE:
                from src.protocols.tcp.tcp_protocol import CustomLISParser as TCPCustomLISParser
                self.parsers['tcp_custom_lis'] = TCPCustomLISParser()
                logger.info("自定义LIS协议解析器（TCP）注册成功")
            else:
                logger.warning("TCP模块不可用，自定义LIS协议解析器不可用")
        except Exception as e:
            logger.warning(f"自定义LIS协议解析器（TCP）不可用: {e}")

    def set_communication_type(self, comm_type: str):
        """设置通信类型（TCP或串口）"""
        if comm_type in [CommunicationType.SERIAL, CommunicationType.TCP]:
            # 如果当前有连接，先断开
            if self.is_connected:
                self.stop_communication()
            
            self.communication_type = comm_type
            logger.info(f"通信类型已设置为: {comm_type}")
        else:
            logger.error(f"不支持的通信类型: {comm_type}")

    def get_communication_type(self) -> str:
        """获取当前通信类型"""
        return self.communication_type

    def setup_serial_port(self, port: str = None, baudrate: int = None, data_bits: int = 8, 
                         stop_bits: int = 1, parity: str = 'N'):
        """设置串口"""
        if not SERIAL_AVAILABLE:
            logger.error("串口模块不可用")
            return False
        
        try:
            # 如果没有提供端口和波特率，尝试从数据库加载
            if port is None or baudrate is None:
                if self.db_manager:
                    port = port or self.db_manager.get_system_config("serial_port") or "COM3"
                    baudrate = baudrate or int(self.db_manager.get_system_config("baudrate") or "115200")
                else:
                    port = port or "COM3"
                    baudrate = baudrate or 115200
            
            self.serial_port = SerialPort(port, baudrate)
            self.communication_type = CommunicationType.SERIAL
            logger.info(f"串口已设置: {port}@{baudrate}")
            return True
            
        except Exception as e:
            logger.error(f"设置串口失败: {e}")
            return False

    def setup_tcp_client(self, host: str = None, port: int = None):
        """设置TCP客户端"""
        if not TCP_AVAILABLE:
            logger.error("TCP模块不可用")
            return False
        
        try:
            # 如果没有提供主机和端口，尝试从数据库加载
            if host is None or port is None:
                if self.db_manager:
                    host = host or self.db_manager.get_system_config("tcp_host") or "127.0.0.1"
                    port = port or int(self.db_manager.get_system_config("tcp_port") or "5000")
                else:
                    host = host or "127.0.0.1"
                    port = port or 5000
            
            self.tcp_client = TCPClient(host, port)
            self.communication_type = CommunicationType.TCP
            logger.info(f"TCP客户端已设置: {host}:{port}")
            return True
            
        except Exception as e:
            logger.error(f"设置TCP客户端失败: {e}")
            return False

    def setup_tcp_server(self, host: str = "0.0.0.0", port: int = 5001, max_clients: int = 10):
        """设置TCP服务器"""
        if not TCP_AVAILABLE:
            logger.error("TCP模块不可用")
            return False
        
        try:
            from src.protocols.tcp.tcp_server import TCPServer
            self.tcp_server = TCPServer(host, port, max_clients)
            logger.info(f"TCP服务器已设置: {host}:{port}")
            return True
            
        except Exception as e:
            logger.error(f"设置TCP服务器失败: {e}")
            return False

    def start_communication(self) -> bool:
        """启动通信"""
        try:
            if self.communication_type == CommunicationType.SERIAL:
                if self.serial_port:
                    if self.serial_port.open():
                        # 启动串口通信线程
                        self.comm_thread = SerialCommunicationThread(self.serial_port, self.data_callback, self)
                        self.comm_thread.start()
                        self.is_connected = True
                        logger.info("串口通信已启动")
                        
                        # 记录通信启动日志
                        if self.system_logger:
                            self.system_logger.log_communication_event(
                                "启动通信",
                                "串口通信已启动",
                                connection_info={"type": "Serial", "port": self.serial_port.port, "baudrate": self.serial_port.baudrate},
                                success=True
                            )
                        return True
                    else:
                        logger.error("串口打开失败")
                        return False
                else:
                    logger.error("串口未设置")
                    return False
                    
            elif self.communication_type == CommunicationType.TCP:
                if self.tcp_client:
                    if self.tcp_client.connect():
                        # 启动TCP通信线程
                        self.comm_thread = TCPCommunicationThread(self.tcp_client, self.data_callback, self)
                        self.comm_thread.start()
                        self.is_connected = True
                        logger.info("TCP通信已启动")
                        
                        # 记录通信启动日志
                        if self.system_logger:
                            self.system_logger.log_communication_event(
                                "启动通信",
                                "TCP通信已启动",
                                connection_info={"type": "TCP", "host": self.tcp_client.host, "port": self.tcp_client.port},
                                success=True
                            )
                        return True
                    else:
                        logger.error("TCP连接失败")
                        return False
                else:
                    logger.error("TCP客户端未设置")
                    return False
            else:
                logger.error(f"不支持的通信类型: {self.communication_type}")
                return False
                
        except Exception as e:
            logger.error(f"启动通信失败: {e}")
            return False

    def stop_communication(self) -> bool:
        """停止通信"""
        try:
            if self.comm_thread:
                self.comm_thread.stop()
                self.comm_thread.wait()
                self.comm_thread = None
            
            if self.serial_port:
                self.serial_port.close()
            
            if self.tcp_client:
                self.tcp_client.disconnect()
            
            self.is_connected = False
            logger.info("通信已停止")
            return True
            
        except Exception as e:
            logger.error(f"停止通信失败: {e}")
            return False

    def test_connection(self) -> bool:
        """测试连接"""
        try:
            if self.communication_type == CommunicationType.SERIAL:
                if self.serial_port:
                    # 测试串口连接
                    return self.serial_port.test_connection()
                else:
                    logger.warning("串口未设置")
                    return False
                    
            elif self.communication_type == CommunicationType.TCP:
                if self.tcp_client:
                    # 测试TCP连接
                    return self.tcp_client.test_connection()
                else:
                    logger.warning("TCP客户端未设置")
                    return False
            else:
                logger.error(f"不支持的通信类型: {self.communication_type}")
                return False
                
        except Exception as e:
            logger.error(f"测试连接失败: {e}")
            return False

    def send_data(self, data: bytes) -> bool:
        """发送数据"""
        try:
            if self.communication_type == CommunicationType.TCP and self.tcp_client:
                return self.tcp_client.write(data)
            elif self.communication_type == CommunicationType.SERIAL and self.serial_port:
                return self.serial_port.write(data)
            else:
                logger.warning("当前通信类型不支持或未设置")
                return False
                
        except Exception as e:
            logger.error(f"发送数据失败: {e}")
            return False

    def set_data_callback(self, callback: Callable[[dict], None]):
        """设置数据回调函数"""
        self.data_callback = callback
        logger.info("数据回调函数已设置")

    def on_data_received(self, data: bytes):
        """接收到数据"""
        try:
            self.message_count += 1
            self.data_received.emit(data)
            
            # 记录接收日志
            if self.system_logger:
                self.system_logger.log_communication_event(
                    "数据接收",
                    f"接收到 {len(data)} 字节数据",
                    connection_info={"type": self.communication_type, "message_count": self.message_count},
                    success=True
                )
            
            logger.debug(f"接收到数据: {len(data)} 字节")
            
        except Exception as e:
            logger.error(f"处理接收数据失败: {e}")
            self.error_occurred.emit(str(e))

    def on_message_processed(self, message: dict):
        """消息处理完成"""
        try:
            self.message_processed.emit(message)
            
            # 记录消息处理日志
            if self.system_logger:
                self.system_logger.log_communication_event(
                    "消息处理",
                    f"消息处理完成: {message.get('protocol', 'Unknown')}",
                    connection_info={"type": self.communication_type, "message_count": self.message_count},
                    success=True
                )
            
            logger.info(f"消息处理完成: {message.get('protocol', 'Unknown')}")
            
        except Exception as e:
            logger.error(f"处理消息完成事件失败: {e}")
            self.error_occurred.emit(str(e))

    def create_sample_from_parsed_data(self, parsed_data: dict, raw_data: str = "", communication_type: str = "TCP") -> 'Sample':
        """从解析的数据创建样本对象"""
        try:
            if not self.data_processor:
                logger.error("数据处理器不可用")
                return None
            
            # 使用数据处理器创建样本
            sample = self.data_processor.create_sample_from_parsed_data(parsed_data, raw_data, communication_type)
            
            if sample:
                logger.info(f"成功创建样本: {sample.id}")
            else:
                logger.warning("创建样本失败")
            
            return sample
            
        except Exception as e:
            logger.error(f"创建样本失败: {e}")
            return None

    def extract_sample_info(self, parsed_data: dict, communication_type: str = "TCP") -> dict:
        """提取样本信息"""
        try:
            if not self.data_processor:
                logger.error("数据处理器不可用")
                return {}
            
            # 使用数据处理器提取样本信息
            sample_info = self.data_processor.extract_sample_info(parsed_data, communication_type)
            return sample_info
            
        except Exception as e:
            logger.error(f"提取样本信息失败: {e}")
            return {}

    def get_connection_info(self) -> dict:
        """获取连接信息"""
        try:
            info = {
                "type": self.communication_type,
                "connected": self.is_connected,
                "message_count": self.message_count
            }
            
            if self.communication_type == CommunicationType.SERIAL and self.serial_port:
                info.update({
                    "port": self.serial_port.port,
                    "baudrate": self.serial_port.baudrate,
                    "is_open": self.serial_port.is_open()
                })
            elif self.communication_type == CommunicationType.TCP and self.tcp_client:
                info.update({
                    "host": self.tcp_client.host,
                    "port": self.tcp_client.port,
                    "is_connected": self.tcp_client.is_connected()
                })
            
            return info
            
        except Exception as e:
            logger.error(f"获取连接信息失败: {e}")
            return {}

    def get_protocol_info(self, parsed_data: dict, communication_type: str = "TCP") -> str:
        """获取协议信息"""
        try:
            # 根据通信类型确定协议名称
            base_protocol = parsed_data.get('protocol', 'CUSTOM_LIS')
            if communication_type == "TCP":
                protocol = f"TCP_{base_protocol}"
            else:
                protocol = f"SERIAL_{base_protocol}"
            
            return protocol
            
        except Exception as e:
            logger.error(f"获取协议信息失败: {e}")
            return "UNKNOWN"

    # TCP服务器相关方法
    def start_tcp_server(self) -> bool:
        """启动TCP服务器"""
        try:
            if not self.tcp_server:
                logger.error("TCP服务器未设置")
                return False
            
            if self.tcp_server.start():
                logger.info("TCP服务器启动成功")
                return True
            else:
                logger.error("TCP服务器启动失败")
                return False
                
        except Exception as e:
            logger.error(f"启动TCP服务器失败: {e}")
            return False

    def stop_tcp_server(self) -> bool:
        """停止TCP服务器"""
        try:
            if not self.tcp_server:
                logger.error("TCP服务器未设置")
                return False
            
            if self.tcp_server.stop():
                logger.info("TCP服务器停止成功")
                return True
            else:
                logger.error("TCP服务器停止失败")
                return False
                
        except Exception as e:
            logger.error(f"停止TCP服务器失败: {e}")
            return False

    def is_tcp_server_running(self) -> bool:
        """检查TCP服务器是否运行"""
        try:
            if not self.tcp_server:
                return False
            return self.tcp_server.is_running()
        except Exception as e:
            logger.error(f"检查TCP服务器状态失败: {e}")
            return False

    def get_tcp_server_client_count(self) -> int:
        """获取TCP服务器客户端数量"""
        try:
            if not self.tcp_server:
                return 0
            return self.tcp_server.get_client_count()
        except Exception as e:
            logger.error(f"获取TCP服务器客户端数量失败: {e}")
            return 0

    def get_tcp_server_client_list(self) -> list:
        """获取TCP服务器客户端列表"""
        try:
            if not self.tcp_server:
                return []
            return self.tcp_server.get_client_list()
        except Exception as e:
            logger.error(f"获取TCP服务器客户端列表失败: {e}")
            return [] 